nnotifd NSDistNotifで制御するObj-C製CL実行デーモンみたいなの
概要
コマンドラインから起動して、Mac内を駆け巡るNSDistributedNotificationを受信、
特定の形式だった場合、コマンドラインを実行するプログラムを作った。
Macアプリではなく、Macコマンドラインアプリ。
nnotifdというコマンド名にした。
https://github.com/sassembla/nnotifd
SocketRoundabout
(WebSocketP、BT、HTTP、NSDistNotif、他、通信プロトコルを相互接続するツール)
と組み合わせて使う。
単体でも使い道があるとは思うが、わざわざそのために脳みそ使って考える必要も無いだろう。
動機
どんなニーズがこれを作らせたか、というと、
・Mac環境、サーバサイドで動く、コマンドライン実行クライアントが欲しかった
→SocketRoundaboutがその機能を持ちたくないので、コマンドラインを外部で動かすもの、という位置づけのプロダクトが必要だった。
・コマンドライン実行自体を、NSDistributedNotificationをトリガーとして行いたかった
→完全にSocketRoundaboutが話せるプロトコルだった、という都合。
→そういえば大昔につくったObj-Cサーバあったよね!
ということで、改造していろんな機能オミットしまくって、こうなった。
ちなみにデーモンって言ってるけどまだぜんぜんデーモンじゃない。
形式
会社でつかってる独自形式(文字列+JSON)をベースに、適当にコピーした形式を使っている。
SublimeSocketとほぼ同系統だけど、こっちのほうが機能が圧倒的に少ない。必要ないしな。
全体
nn:[JSONARRAY]
ヘッダ
nn:
パラメータ
[JSONARRAY]
という形の文字列を送り込むと、コマンドラインとパラメータとパイプを解釈して、コマンドラインとして実行される。
例's
始動
nnotifd -c start -i IDENTITY
で、アイデンティティ = nnotifdが受信するチャンネル、という風に設定して起動できる。
別に起動と同時にスタートしないでもいいんだけど、-iでの「受信するアイデンティティの決定」だけは必須。
nnotifdとのコミュニケーションには、NSDistributedNotificationを生成すればOKで、
これはキーとかが合ってればプロセス間を跨ぎ放題、なんでも送ってOKというゆっるーい感じになっている。
実行順は発行順と同じにならない(順保証がされない)ので、使いたい部分だけ注意して作った。
実際には準保証をするための仕掛けもNSなんちゃらには用意されているが、テストしづらかったので、これから順保証モードとして着手する。
なんかNSDistNotif越しの実行がしたい場合、
nnotifdを起動したあと、
付属のnnotif(入力した文字列をNSDistNotifにして発行するツール)で送付するか、どっかObj-Cで書いて送り込む。
nnotif -t IDENTITY -k NN_DEFAULT_ROUTE -i nn@ -kill
これでkillできる。
-iはnnotifのオプションで、input。 nn@以降の文字をnnotifdに対するコマンドとしてIDENTITYに対して送り込む。
Obj-Cで書く場合、
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:IDENTITY object:nil userInfo:dict deliverImmediately:YES];
で良いと思う。dictの中身はパラメータになる。
コレに関しては、nnotifが | を受けられるため、コマンドラインから使えるほうが万倍いろんなことができる。
nnotifdで特定のコマンドラインを実行したい場合、
nnotif -t IDENTITY -k NN_DEFAULT_ROUTE -i nn@ -e nn:["/bin/pwd"]
とかで、pwdが実行できる。
nn@ までが入力のためのヘッダ、-eから先がnntoifdで実行されるコマンドの独自形式JSONArray。
pwdがフルパスになってるのは、これの内部実装がNSTaskを使用しているので、コマンドのありかのパスを総て書かないと動かないため。
nnotifd内で使用したいコマンドに対してパイプを使う事もできて、
nnotif -t IDENTITY -k NN_DEFAULT_ROUTE -i nn@ -e nn:["/bin/cat","/SOMEWHERE/SOMETHING.txt","|","/usr/bin/grep","-e","KEYWORD"]
とかで、
/SOMEWHERE/SOMETHING.txt に対してgrep KEYWORD を実行する、みたいなのができる。
おまけで、nnotif自体がパイプを扱えるので、
tail -f /SOMEWHERE/SOMETHING.log | nnotif -t IDENTITY -k NN_DEFAULT_ROUTE
とかで、tail結果をダイレクトに、連続した状態でどこかへと送り込める。
もちろんnnotifdのなかでnnotifを使用して別のNSDistNotifを発生させることもできる。
これで、例えばサーバからのメッセージを受けて特定のコマンドラインを実行したり、
実行した内容を同種の通信手段を使っているSocketのおばけみたいなプロダクトに送り込んだりできる。
具体的な用途
特定のコマンドラインを実行し、その結果を、nnotifなどを使い、NSDistNotifで送り出す。
NSDistNotification -> BT とか、
NSDistNotification -> WebSocket とか、そういう転送ができるツールがあるので、
そのツール自体のコントロールとか、プッシュの「起点」に使用する。
そうっとう異様なニーズに応える代物。
組み合わせで、WebSocketClientをサーバサイドでnodeとかより安定した挙動できるように動かそう、みたいな
ニーズに応えるために作った。
ぶっちゃけnodeの難解なコントロールに耐えられなかった人間が狂気で作った何かのためのパーツ。